package collection_test.queue.blcok_queue;

import org.junit.Test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class LinkedBlockingQueueTest {


    /**
     * 阻塞队列LinkedBlockingQueue和ArrayBlockingQueue的应用
     */
    @Test
    public void test() throws InterruptedException {
        //除了拥有队列的方法之外，阻塞队列多了两个方法： put和 take  用于阻塞
        LinkedBlockingQueue blockingQueue = new LinkedBlockingQueue(2);  //无界队列

        new Thread(() -> {
            try {
                System.out.println("我准备要拿元素了。。。");
                Object take = blockingQueue.take();
                System.out.println("我拿到了元素了");
                System.out.println("5秒后，我需要消费一个元素，让盘子不是满的");
                TimeUnit.SECONDS.sleep(5);
                System.out.println("我消费这个元素了····");
                blockingQueue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                System.out.println("我5秒后放元素。。。");
                TimeUnit.SECONDS.sleep(5);
                blockingQueue.put(1);
                System.out.println("我放了元素了");
                blockingQueue.put(2);
                blockingQueue.put(3);
                System.out.println("我再放1个元素，但是已经满了，需要等待有人消费掉里面的1个元素");
                blockingQueue.put(4);
                System.out.println("这次也放成功了！");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }).start();


        ArrayBlockingQueue blockingArrayQueue = new ArrayBlockingQueue(2);//有界队列
        blockingArrayQueue.offer(1); //offer 如果满了，会返回false
        blockingArrayQueue.add(1); //add如果满了 会抛异常

        while (true) ;
    }
}
